package com.hippo.core.util;

import com.codeborne.selenide.Condition;
import com.codeborne.selenide.Configuration;
import com.codeborne.selenide.SelenideElement;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;

import static com.codeborne.selenide.Selectors.*;
import static com.codeborne.selenide.Selenide.*;

/**
 * @author hippo
 */
@Slf4j
public class BrowserOpt {

    public BrowserOpt() {
        if (SystemUtil.isWindows()) {
            System.setProperty("webdriver.chrome.driver", "driver/chromedriver.exe");
        } else {
            System.setProperty("webdriver.chrome.driver", "driver/chromedriver");
        }
        Configuration.browser = "chrome";
    }

    /**
     * 无头运行
     *
     * @param value 是否
     */
    public void execHeadless(Boolean value) {
        Configuration.headless = value;
        Configuration.browserSize = "1600x800";
    }

    /**
     * 运行完不关闭浏览器
     */
    public void execHoldBrowserOpen() {
        Configuration.holdBrowserOpen = true;
    }

    /**
     * 设置全屏
     */
    public void execStartMaximized() {
        Configuration.startMaximized = true;
    }

    /**
     * 打开网址
     *
     * @param url 网址
     */
    public void execOpen(String url) {
        open(url);
    }

    /**
     * 截图
     *
     * @param fileName 文件名
     */
    public String execScreenshot(String fileName) throws IOException {
        String screenshot = screenshot(fileName);
        return screenshot;
    }

    /**
     * 强制等待
     *
     * @param time 时间
     */
    public void execSleep(String time) {
        long l = Long.parseLong(time);
        sleep(l * 1000);
    }

    /**
     * 上传文件
     *
     * @param type     定位类型
     * @param location 定位表达式
     * @param path     服务器文件地址
     */
    public void execUpload(String type, String location, String path) {
        SelenideElement element = element(type, location);
        element.uploadFile(UrlToFIle.getFile(path));
    }

    /**
     * 关闭窗口
     */
    public void execCloseWindow() {
//        closeWindow();
//        close();
        closeWebDriver();
    }

    /**
     * 刷新
     */
    public void execRefresh() {
        refresh();
    }

    /**
     * 获取标题
     */
    public String execTitle() {
        return title();

    }

    /**
     * 切换窗口
     *
     * @param title 名称
     */
    public void execSwitchToWindow(String title) {
        switchTo().window(title);
    }

    /**
     * 切换iframe
     *
     * @param type     定位类型
     * @param location 定位表达式
     */
    public void execSwitchToIframe(String type, String location) {
        SelenideElement element = element(type, location);
        switchTo().frame(element);
    }

    /**
     * 执行js
     *
     * @param type     定位类型
     * @param location 定位表达式
     * @param jsCode   代码
     */

    public void execElJavaScript(String type, String location, String jsCode) {
        SelenideElement element = element(type, location);
        executeJavaScript(jsCode, element);
        executeJavaScript(jsCode);
    }

    public void execJavaScript(String jsCode) {
        executeJavaScript(jsCode);
    }

    /**
     * 元素定位
     *
     * @param type     定位类型
     * @param location 定位表达式
     * @return el
     */
    public SelenideElement element(String type, String location) {
        SelenideElement el = null;
        switch (type) {
            case "id":
                el = $(byId(location));
                break;
            case "className":
                el = $(byClassName(location));
                break;
            case "cssSelector":
                el = $(byCssSelector("." + location));
                break;
            case "name":
                el = $(byName(location));
                break;
            case "linkText":
                el = $(byLinkText(location));
                break;
            case "tagName":
                el = $(byTagName(location));
                break;
            case "xpath":
                el = $(byXpath(location));
                break;
            case "partialLinkText":
                el = $(byPartialLinkText(location));
                break;
            case "text":
                el = $(byText(location));
                break;
            case "withText":
                el = $(withText(location));
                break;
            case "byTitle":
                el = $(byTitle(location));
                break;
            case "byValue":
                el = $(byValue(location));
                break;
        }
        if (el.toString().contains("NoSuchElementException")) {
            log.warn("获取元素失败：" + el.toString());
        } else {
            log.info("获取元素成功：" + el.toString());
        }
        return el;
    }

    /**
     * 输入值-追加
     *
     * @param type     定位类型
     * @param location 定位表达式
     * @param value    输入值
     */
    public void execAddSetValue(String type, String location, String value) {
        SelenideElement element = element(type, location);
        element.setValue(value);
    }

    /**
     * 输入值-覆盖
     *
     * @param type     定位类型
     * @param location 定位表达式
     * @param value    输入值
     */
    public void execSetValue(String type, String location, String value) {
        SelenideElement element = element(type, location);
        element.clear();
        element.setValue(value);
    }

    /**
     * 点击
     *
     * @param type     定位类型
     * @param location 定位表达式
     */
    public void execClick(String type, String location) {
        SelenideElement element = element(type, location);
        element.click();
    }

    /**
     * 双击
     *
     * @param type     定位类型
     * @param location 定位表达式
     */
    public void execDoubleClick(String type, String location) {
        SelenideElement element = element(type, location);
        element.doubleClick();
    }

    /**
     * 右击
     *
     * @param type     定位类型
     * @param location 定位表达式
     */
    public void execContextClick(String type, String location) {
        SelenideElement element = element(type, location);
        element.contextClick();
    }

    /**
     * 悬浮
     *
     * @param type     定位类型
     * @param location 定位表达式
     */
    public void execHover(String type, String location) {
        SelenideElement element = element(type, location);
        element.hover();
    }

    /**
     * 回车
     *
     * @param type     定位类型
     * @param location 定位表达式
     */
    public void execPressEnter(String type, String location) {
        SelenideElement element = element(type, location);
        element.pressEnter();
    }

    /**
     * 回车
     *
     * @param type     定位类型
     * @param location 定位表达式
     */
    public void execPressEscape(String type, String location) {
        SelenideElement element = element(type, location);
        element.pressEscape();
    }

    /**
     * radio切换
     *
     * @param type     定位类型
     * @param location 定位表达式
     * @param value    切换radio的值
     */
    public void execSelectRadio(String type, String location, String value) {
        SelenideElement element = element(type, location);
        element.selectRadio(value);
    }

    /**
     * 断言元素存在
     *
     * @param type     定位类型
     * @param location 定位表达式
     */
    public void assertExist(String type, String location) {
        SelenideElement element = element(type, location);
        element.should(Condition.exist);
    }

    public void assertNotExist(String type, String location) {
        SelenideElement element = element(type, location);
        element.shouldNot(Condition.exist);
    }

    /**
     * 断言元素显示
     *
     * @param type     定位类型
     * @param location 定位表达式
     */
    public void assertVisible(String type, String location) {
        SelenideElement element = element(type, location);
        element.should(Condition.visible);
    }

    public void assertNotVisible(String type, String location) {
        SelenideElement element = element(type, location);
        element.shouldNot(Condition.visible);
    }


    /**
     * 断言元素内存在文本
     *
     * @param type     定位类型
     * @param location 定位表达式
     * @param value    text值
     */
    public void assertText(String type, String location, String value) {
        SelenideElement element = element(type, location);
        element.should(Condition.text(value));
    }

    public void assertNotText(String type, String location, String value) {
        SelenideElement element = element(type, location);
        element.shouldNot(Condition.text(value));
    }

    /**
     * 断言元素内存在值
     *
     * @param type     定位类型
     * @param location 定位表达式
     * @param value    value值
     */
    public void assertValue(String type, String location, String value) {
        SelenideElement element = element(type, location);
        element.should(Condition.value(value));
    }

    public void assertNotValue(String type, String location, String value) {
        SelenideElement element = element(type, location);
        element.shouldNot(Condition.value(value));
    }

    /**
     * 断言元素内存在属性
     *
     * @param type     定位类型
     * @param location 定位表达式
     * @param value    value值
     */
    public void assertAttribute(String type, String location, String name, String value) {
        SelenideElement element = element(type, location);
        element.should(Condition.attribute(name, value));
    }

    public void assertNotAttribute(String type, String location, String name, String value) {
        SelenideElement element = element(type, location);
        element.shouldNot(Condition.attribute(name, value));
    }

}